// Copyright 2021 ETH Zurich and University of Bologna.
// Solderpad Hardware License, Version 0.51, see LICENSE for details.
// SPDX-License-Identifier: SHL-0.51
//
// Author: Matteo Perotti <mperotti@iis.ee.ethz.ch>
//         Basile Bougenot <bbougenot@student.ethz.ch>

#include "float_macros.h"
#include "vector_macros.h"

// Simple random test with similar values
void TEST_CASE1(void) {
  VSET(16, e16, m1);
  //               0.9175,  0.0740, -0.0362,  0.2961,  0.6226, -0.8032,  0.7749,
  //               0.8188,  0.2019,  0.4885,  0.5669, -0.1743,  0.4404,  0.0618,
  //               0.8252, -0.5947
  VLOAD_16(v2, 0x3b57, 0x2cbc, 0xa8a3, 0x34bd, 0x38fb, 0xba6d, 0x3a33, 0x3a8d,
           0x3276, 0x37d1, 0x3889, 0xb194, 0x370c, 0x2bea, 0x3a9a, 0xb8c2);
  //               0.2812, -0.6733,  0.3289,  0.9609, -0.6841,  0.5488, -0.1401,
  //               0.5591,  0.2759, -0.6973,  0.1418,  0.2389, -0.3308,  0.8867,
  //               0.8936,  0.3611
  VLOAD_16(v3, 0x3480, 0xb963, 0x3543, 0x3bb0, 0xb979, 0x3864, 0xb07c, 0x3879,
           0x346a, 0xb994, 0x308a, 0x33a5, 0xb54b, 0x3b18, 0x3b26, 0x35c7);
  //               0.4780, -0.1810,  0.2800,  0.7529,  0.6484, -0.9526,
  //               0.5947,  1.0000, -0.1874,  0.2949, -0.4280,  0.6934,  0.5444,
  //               0.8823, -0.8911,  0.7603
  VLOAD_16(v1, 0x37a6, 0xb1cb, 0x347b, 0x3a06, 0x3930, 0xbb9f, 0x38c2, 0x3c00,
           0xb1ff, 0x34b8, 0xb6d9, 0x398c, 0x385b, 0x3b0f, 0xbb21, 0x3a15);
  asm volatile("vfmsac.vv v1, v2, v3");
  //              -0.2200,  0.1312, -0.2920, -0.4683, -1.0742,  0.5117, -0.7031,
  //              -0.5420,  0.2430, -0.6357,  0.5083, -0.7349, -0.6904, -0.8276,
  //              1.6289, -0.9751
  VCMP_U16(1, v1, 0xb30a, 0x3033, 0xb4ac, 0xb77e, 0xbc4c, 0x3818, 0xb9a0,
           0xb856, 0x33c7, 0xb916, 0x3811, 0xb9e1, 0xb985, 0xba9f, 0x3e84,
           0xbbcd);

  VSET(16, e32, m1);
  //              -0.90310860,  0.30282700,  0.54854167, -0.38732994,
  //              0.92121714,  0.99595129, -0.10263380,  0.83759040,
  //              -0.23468767,  0.03914077, -0.46234205,  0.38326120,
  //              0.36417511, -0.50103557,  0.36991179,  0.44718841
  VLOAD_32(v2, 0xbf673220, 0x3e9b0c24, 0x3f0c6d3a, 0xbec6501c, 0x3f6bd4e3,
           0x3f7ef6aa, 0xbdd231ab, 0x3f566c53, 0xbe7051f7, 0x3d205212,
           0xbeecb819, 0x3ec43ad0, 0x3eba7529, 0xbf0043de, 0x3ebd6514,
           0x3ee4f5e1);
  //               0.84989786, -0.04543342, -0.74596256, -0.30687407,
  //               -0.30795863,  0.57084304,  0.51653886, -0.97366458,
  //               0.49300706,  0.62932760,  0.45846274, -0.73850167,
  //               -0.42686453, -0.31419462, -0.47245970, -0.87721694
  VLOAD_32(v3, 0x3f5992e8, 0xbd3a1866, 0xbf3ef767, 0xbe9d1e99, 0xbe9dacc1,
           0x3f1222c5, 0x3f043be4, 0xbf794215, 0x3efc6b6c, 0x3f211b9d,
           0x3eeabba1, 0xbf3d0e72, 0xbeda8dfd, 0xbea0de1e, 0xbef1e63d,
           0xbf60914a);
  //              -0.76813585,  0.87161541, -0.67958647, -0.98584491,
  //              0.12284227, -0.04006640, -0.93113720, -0.93526161,
  //              -0.27461481,  0.64110506,  0.61687475, -0.43741968,
  //              0.70502371,  0.37014356, -0.98105848,  0.77993429
  VLOAD_32(v1, 0xbf44a48d, 0x3f5f2230, 0xbf2df961, 0xbf7c6055, 0x3dfb94bb,
           0xbd241caa, 0xbf6e5f02, 0xbf6f6d4e, 0xbe8c9a50, 0x3f241f76,
           0x3f1deb81, 0xbedff579, 0x3f347c6f, 0x3ebd8375, 0xbf7b26a6,
           0x3f47a9c6);
  asm volatile("vfmsac.vv v1, v2, v3");
  //               0.00058579, -0.88537389,  0.27039492,  1.10470641,
  //               -0.40653905,  0.60859829,  0.87812287,  0.11972952,
  //               0.15891212, -0.61647266, -0.82884133,  0.15438065,
  //               -0.86047715, -0.21272089,  0.80629003, -1.17221546
  VCMP_U32(2, v1, 0x3a198f11, 0xbf62a7dd, 0x3e8a7134, 0x3f8d6705, 0xbed025e3,
           0x3f1bcd19, 0x3f60cca9, 0x3df534be, 0x3e22b9dd, 0xbf1dd127,
           0xbf542ef3, 0x3e1e15f6, 0xbf5c483b, 0xbe59d381, 0x3f4e6907,
           0xbf960b29);

  VSET(16, e64, m1);
  //               0.0971325394189311,  0.6403859199401045,  0.3478142243141771,
  //               -0.4702414117546168,  0.8862438155310881, 0.6157878617136987,
  //               -0.9954501284062294, -0.2761157935600853,
  //               -0.7189549700888722, -0.2302799669824283, 0.0093666993515229,
  //               0.9188774299961215, -0.4297410504980956,  0.2729294776457381,
  //               -0.1419575372981836, -0.8472908703054822
  VLOAD_64(v2, 0x3fb8ddad982e8680, 0x3fe47e0a9cdec59e, 0x3fd6429697a0d4f8,
           0xbfde186f6f2d8030, 0x3fec5c1bfd7f9ffe, 0x3fe3b488beeab100,
           0xbfefdaba3a49b85e, 0xbfd1abe193cffa54, 0xbfe701adda7a81f6,
           0xbfcd79d05f8e86d0, 0x3f832ed91b170d00, 0x3fed6771a3dbb538,
           0xbfdb80e09b68d514, 0x3fd177ad33269468, 0xbfc22baa220ee628,
           0xbfeb1d01be452a62);
  //              -0.2416734667201210, -0.2737616510555549,  0.6084509432766920,
  //              -0.4000545529138850,  0.5985258122916897, -0.9559409603601607,
  //              0.5010970610326939,  0.5772808284477746, -0.4551243154247406,
  //              0.6584804564152213,  0.6542532086910551, -0.2215058802905889,
  //              0.3203723346938081,  0.0696368102348055,  0.8882580549203218,
  //              0.7725843936650791
  VLOAD_64(v3, 0xbfceef27f9efdac8, 0xbfd1854f968baf44, 0x3fe3786e1cd2fff2,
           0xbfd99a7e695862ec, 0x3fe3271f9ab3593a, 0xbfee97117f34eb4c,
           0x3fe008fcb4283a76, 0x3fe27915a4d94fb2, 0xbfdd20c1bc974608,
           0x3fe512459b2b7912, 0x3fe4efa46cd43256, 0xbfcc5a4dffdc2170,
           0x3fd480faf7036588, 0x3fb1d3b7ce8e6640, 0x3fec6c9c280952c6,
           0x3fe8b902e80620ce);
  //              -0.8982912058335177,  0.5582779858188844, -0.3988318240568800,
  //              0.0267896464795028,  0.8241806039831361,  0.2839220639224551,
  //              -0.4781090814672235, -0.1240154287362147,  0.4586341020154134,
  //              -0.6132901056934972,  0.1207753636997857,  0.4420874266235846,
  //              0.8256868703569773,  0.0642541522901756, -0.3012484644971416,
  //              0.7323810741358745
  VLOAD_64(v1, 0xbfecbecd32eadc10, 0x3fe1dd69cb65674e, 0xbfd98675ea3b69b0,
           0x3f9b6ebebe00e300, 0x3fea5fb000835cf4, 0x3fd22bc772ca399c,
           0xbfde9956d534a0f8, 0xbfbfbf79a29f1810, 0x3fdd5a42d93f2348,
           0xbfe3a012925d3f1c, 0x3fbeeb225d40ca30, 0x3fdc4b290fd48cd4,
           0x3fea6c06df1d6f14, 0x3fb072f5cab7f020, 0xbfd347a7a3bf1174,
           0x3fe76faa6f33ef10);
  asm volatile("vfmsac.vv v1, v2, v3");
  //               0.8748168483008159, -0.7335910925744179,  0.6104597169258920,
  //               0.1613325712615846, -0.2937408044039052, -0.8725789038271781,
  //               -0.0207080522817558, -0.0353809253176660,
  //               -0.1314202134325006,  0.4616552479316257,
  //               -0.1146471705942074, -0.6456241806340295,
  //               -0.9633640140188219, -0.0452482140478748, 0.1751535385353780,
  //               -1.3869847774287927
  VCMP_U64(3, v1, 0x3febfe7fe72e2334, 0xbfe7799406e7cf1f, 0x3fe388e2d0f71ba3,
           0x3fc4a68bb2ac8e62, 0xbfd2cca63b1a97a5, 0xbfebec2a97e3c096,
           0xbf95347ddd418906, 0xbfa21d72da487f01, 0xbfc0d260a75ceb46,
           0x3fdd8bc273f9289e, 0xbfbd59845847f323, 0xbfe4a8f40aaa8efa,
           0xbfeed3e0c4cb54ff, 0xbfa72ac61f1378a7, 0x3fc66b6e5fe4e141,
           0xbff63116f331b43d);
};

// Simple random test with similar values (masked)
// The numbers are the same of TEST_CASE1
void TEST_CASE2(void) {
  VSET(16, e16, m1);
  //               0.9175,  0.0740, -0.0362,  0.2961,  0.6226, -0.8032,  0.7749,
  //               0.8188,  0.2019,  0.4885,  0.5669, -0.1743,  0.4404,  0.0618,
  //               0.8252, -0.5947
  VLOAD_16(v2, 0x3b57, 0x2cbc, 0xa8a3, 0x34bd, 0x38fb, 0xba6d, 0x3a33, 0x3a8d,
           0x3276, 0x37d1, 0x3889, 0xb194, 0x370c, 0x2bea, 0x3a9a, 0xb8c2);
  //               0.2812, -0.6733,  0.3289,  0.9609, -0.6841,  0.5488, -0.1401,
  //               0.5591,  0.2759, -0.6973,  0.1418,  0.2389, -0.3308,  0.8867,
  //               0.8936,  0.3611
  VLOAD_16(v3, 0x3480, 0xb963, 0x3543, 0x3bb0, 0xb979, 0x3864, 0xb07c, 0x3879,
           0x346a, 0xb994, 0x308a, 0x33a5, 0xb54b, 0x3b18, 0x3b26, 0x35c7);
  VLOAD_8(v0, 0xAA, 0xAA);
  //               0.4780, -0.1810,  0.2800,  0.7529,  0.6484, -0.9526,
  //               0.5947,  1.0000, -0.1874,  0.2949, -0.4280,  0.6934,  0.5444,
  //               0.8823, -0.8911,  0.7603
  VLOAD_16(v1, 0x37a6, 0xb1cb, 0x347b, 0x3a06, 0x3930, 0xbb9f, 0x38c2, 0x3c00,
           0xb1ff, 0x34b8, 0xb6d9, 0x398c, 0x385b, 0x3b0f, 0xbb21, 0x3a15);
  asm volatile("vfmsac.vv v1, v2, v3, v0.t");
  //               0.4780,  0.1312,  0.2800, -0.4683,  0.6484,  0.5117,  0.5947,
  //               -0.5420, -0.1874, -0.6357, -0.4280, -0.7349,  0.5444,
  //               -0.8276, -0.8911, -0.9751
  VCMP_U16(4, v1, 0x37a6, 0x3033, 0x347b, 0xb77e, 0x3930, 0x3818, 0x38c2,
           0xb856, 0xb1ff, 0xb916, 0xb6d9, 0xb9e1, 0x385b, 0xba9f, 0xbb21,
           0xbbcd);

  VSET(16, e32, m1);
  //              -0.90310860,  0.30282700,  0.54854167, -0.38732994,
  //              0.92121714,  0.99595129, -0.10263380,  0.83759040,
  //              -0.23468767,  0.03914077, -0.46234205,  0.38326120,
  //              0.36417511, -0.50103557,  0.36991179,  0.44718841
  VLOAD_32(v2, 0xbf673220, 0x3e9b0c24, 0x3f0c6d3a, 0xbec6501c, 0x3f6bd4e3,
           0x3f7ef6aa, 0xbdd231ab, 0x3f566c53, 0xbe7051f7, 0x3d205212,
           0xbeecb819, 0x3ec43ad0, 0x3eba7529, 0xbf0043de, 0x3ebd6514,
           0x3ee4f5e1);
  //               0.84989786, -0.04543342, -0.74596256, -0.30687407,
  //               -0.30795863,  0.57084304,  0.51653886, -0.97366458,
  //               0.49300706,  0.62932760,  0.45846274, -0.73850167,
  //               -0.42686453, -0.31419462, -0.47245970, -0.87721694
  VLOAD_32(v3, 0x3f5992e8, 0xbd3a1866, 0xbf3ef767, 0xbe9d1e99, 0xbe9dacc1,
           0x3f1222c5, 0x3f043be4, 0xbf794215, 0x3efc6b6c, 0x3f211b9d,
           0x3eeabba1, 0xbf3d0e72, 0xbeda8dfd, 0xbea0de1e, 0xbef1e63d,
           0xbf60914a);
  VLOAD_8(v0, 0xAA, 0xAA);
  //              -0.76813585,  0.87161541, -0.67958647, -0.98584491,
  //              0.12284227, -0.04006640, -0.93113720, -0.93526161,
  //              -0.27461481,  0.64110506,  0.61687475, -0.43741968,
  //              0.70502371,  0.37014356, -0.98105848,  0.77993429
  VLOAD_32(v1, 0xbf44a48d, 0x3f5f2230, 0xbf2df961, 0xbf7c6055, 0x3dfb94bb,
           0xbd241caa, 0xbf6e5f02, 0xbf6f6d4e, 0xbe8c9a50, 0x3f241f76,
           0x3f1deb81, 0xbedff579, 0x3f347c6f, 0x3ebd8375, 0xbf7b26a6,
           0x3f47a9c6);
  asm volatile("vfmsac.vv v1, v2, v3, v0.t");
  //              -0.76813585, -0.88537389, -0.67958647,  1.10470641,
  //              0.12284227,  0.60859829, -0.93113720,  0.11972952,
  //              -0.27461481, -0.61647266,  0.61687475,  0.15438065,
  //              0.70502371, -0.21272089, -0.98105848, -1.17221546
  VCMP_U32(5, v1, 0xbf44a48d, 0xbf62a7dd, 0xbf2df961, 0x3f8d6705, 0x3dfb94bb,
           0x3f1bcd19, 0xbf6e5f02, 0x3df534be, 0xbe8c9a50, 0xbf1dd127,
           0x3f1deb81, 0x3e1e15f6, 0x3f347c6f, 0xbe59d381, 0xbf7b26a6,
           0xbf960b29);

  VSET(16, e64, m1);
  //               0.0971325394189311,  0.6403859199401045,  0.3478142243141771,
  //               -0.4702414117546168,  0.8862438155310881, 0.6157878617136987,
  //               -0.9954501284062294, -0.2761157935600853,
  //               -0.7189549700888722, -0.2302799669824283, 0.0093666993515229,
  //               0.9188774299961215, -0.4297410504980956,  0.2729294776457381,
  //               -0.1419575372981836, -0.8472908703054822
  VLOAD_64(v2, 0x3fb8ddad982e8680, 0x3fe47e0a9cdec59e, 0x3fd6429697a0d4f8,
           0xbfde186f6f2d8030, 0x3fec5c1bfd7f9ffe, 0x3fe3b488beeab100,
           0xbfefdaba3a49b85e, 0xbfd1abe193cffa54, 0xbfe701adda7a81f6,
           0xbfcd79d05f8e86d0, 0x3f832ed91b170d00, 0x3fed6771a3dbb538,
           0xbfdb80e09b68d514, 0x3fd177ad33269468, 0xbfc22baa220ee628,
           0xbfeb1d01be452a62);
  //              -0.2416734667201210, -0.2737616510555549,  0.6084509432766920,
  //              -0.4000545529138850,  0.5985258122916897, -0.9559409603601607,
  //              0.5010970610326939,  0.5772808284477746, -0.4551243154247406,
  //              0.6584804564152213,  0.6542532086910551, -0.2215058802905889,
  //              0.3203723346938081,  0.0696368102348055,  0.8882580549203218,
  //              0.7725843936650791
  VLOAD_64(v3, 0xbfceef27f9efdac8, 0xbfd1854f968baf44, 0x3fe3786e1cd2fff2,
           0xbfd99a7e695862ec, 0x3fe3271f9ab3593a, 0xbfee97117f34eb4c,
           0x3fe008fcb4283a76, 0x3fe27915a4d94fb2, 0xbfdd20c1bc974608,
           0x3fe512459b2b7912, 0x3fe4efa46cd43256, 0xbfcc5a4dffdc2170,
           0x3fd480faf7036588, 0x3fb1d3b7ce8e6640, 0x3fec6c9c280952c6,
           0x3fe8b902e80620ce);
  VLOAD_8(v0, 0xAA, 0xAA);
  //              -0.8982912058335177,  0.5582779858188844, -0.3988318240568800,
  //              0.0267896464795028,  0.8241806039831361,  0.2839220639224551,
  //              -0.4781090814672235, -0.1240154287362147,  0.4586341020154134,
  //              -0.6132901056934972,  0.1207753636997857,  0.4420874266235846,
  //              0.8256868703569773,  0.0642541522901756, -0.3012484644971416,
  //              0.7323810741358745
  VLOAD_64(v1, 0xbfecbecd32eadc10, 0x3fe1dd69cb65674e, 0xbfd98675ea3b69b0,
           0x3f9b6ebebe00e300, 0x3fea5fb000835cf4, 0x3fd22bc772ca399c,
           0xbfde9956d534a0f8, 0xbfbfbf79a29f1810, 0x3fdd5a42d93f2348,
           0xbfe3a012925d3f1c, 0x3fbeeb225d40ca30, 0x3fdc4b290fd48cd4,
           0x3fea6c06df1d6f14, 0x3fb072f5cab7f020, 0xbfd347a7a3bf1174,
           0x3fe76faa6f33ef10);
  asm volatile("vfmsac.vv v1, v2, v3, v0.t");
  //              -0.8982912058335177, -0.7335910925744179, -0.3988318240568800,
  //              0.1613325712615846,  0.8241806039831361, -0.8725789038271781,
  //              -0.4781090814672235, -0.0353809253176660,  0.4586341020154134,
  //              0.4616552479316257,  0.1207753636997857, -0.6456241806340295,
  //              0.8256868703569773, -0.0452482140478748, -0.3012484644971416,
  //              -1.3869847774287927
  VCMP_U64(6, v1, 0xbfecbecd32eadc10, 0xbfe7799406e7cf1f, 0xbfd98675ea3b69b0,
           0x3fc4a68bb2ac8e62, 0x3fea5fb000835cf4, 0xbfebec2a97e3c096,
           0xbfde9956d534a0f8, 0xbfa21d72da487f01, 0x3fdd5a42d93f2348,
           0x3fdd8bc273f9289e, 0x3fbeeb225d40ca30, 0xbfe4a8f40aaa8efa,
           0x3fea6c06df1d6f14, 0xbfa72ac61f1378a7, 0xbfd347a7a3bf1174,
           0xbff63116f331b43d);
};

// Simple random test with similar values (vector-scalar)
void TEST_CASE3(void) {
  VSET(16, e16, m1);
  double dscalar_16;
  //                              0.3911
  BOX_HALF_IN_DOUBLE(dscalar_16, 0x3642);
  //               0.3203, -0.8521,  0.0744,  0.9370,  0.2056,  0.2866, -0.8379,
  //               -0.2668, -0.0878, -0.5703,  0.1272, -0.6606, -0.6919, 0.9189,
  //               0.6245,  0.9932
  VLOAD_16(v2, 0x3520, 0xbad1, 0x2cc3, 0x3b7f, 0x3294, 0x3496, 0xbab4, 0xb445,
           0xad9f, 0xb890, 0x3012, 0xb949, 0xb989, 0x3b5a, 0x38ff, 0x3bf2);
  //               0.8706,  0.4900, -0.9497,  0.4727, -0.7168,  0.0167, -0.3606,
  //               -0.1565, -0.5142,  0.8271, -0.4783,  0.6318,  0.0842,
  //               -0.6646,  0.1454, -0.3020
  VLOAD_16(v1, 0x3af7, 0x37d7, 0xbb99, 0x3790, 0xb9bc, 0x2445, 0xb5c5, 0xb102,
           0xb81d, 0x3a9e, 0xb7a7, 0x390e, 0x2d63, 0xb951, 0x30a7, 0xb4d5);
  asm volatile("vfmsac.vf v1, %[A], v2" ::[A] "f"(dscalar_16));
  //              -0.7451, -0.8232,  0.9790, -0.1062,  0.7974,  0.0955,  0.0330,
  //              0.0521,  0.4797, -1.0498,  0.5278, -0.8901, -0.3547,  1.0234,
  //              0.0989,  0.6904
  VCMP_U16(7, v1, 0xb9f6, 0xba96, 0x3bd5, 0xaecc, 0x3a61, 0x2e1b, 0x2836,
           0x2aac, 0x37ad, 0xbc33, 0x3839, 0xbb1f, 0xb5ad, 0x3c19, 0x2e54,
           0x3986);

  VSET(16, e32, m1);
  double dscalar_32;
  //                              -0.39704049
  BOX_FLOAT_IN_DOUBLE(dscalar_32, 0xbecb48e4);
  //               0.43844241,  0.13734208,  0.15601240,  0.48965997,
  //               -0.41457745, -0.69918746,  0.38535324,  0.83301985,
  //               0.79336989, -0.03326649, -0.85931808,  0.92554229,
  //               -0.77742523,  0.47821125, -0.53653014, -0.32442030
  VLOAD_32(v2, 0x3ee07b86, 0x3e0ca367, 0x3e1fc1b7, 0x3efab4b6, 0xbed4437f,
           0xbf32fdf3, 0x3ec54d05, 0x3f5540ca, 0x3f4b1a4a, 0xbd084272,
           0xbf5bfc45, 0x3f6cf057, 0xbf470557, 0x3ef4d81b, 0xbf095a0a,
           0xbea61a6b);
  //              -0.73119336,  0.87333083, -0.16325396, -0.30275631,
  //              0.34779423,  0.22721651,  0.47497734, -0.58483958,
  //              -0.24916913,  0.13750601, -0.99799657,  0.66137350,
  //              0.58565408,  0.68887448, -0.74538875,  0.99311894
  VLOAD_32(v1, 0xbf3b2f7d, 0x3f5f929c, 0xbe272c0c, 0xbe9b02e0, 0x3eb21216,
           0x3e68ab72, 0x3ef3303b, 0xbf15b80c, 0xbe7f2631, 0x3e0cce60,
           0xbf7f7cb4, 0x3f294fc6, 0x3f15ed6d, 0x3f305a14, 0xbf3ed1cc,
           0x3f7e3d0b);
  asm volatile("vfmsac.vf v1, %[A], v2" ::[A] "f"(dscalar_32));
  //               0.55711401, -0.92786121,  0.10131072,  0.10834149,
  //               -0.18319020,  0.05038923, -0.62797821,  0.25409698,
  //               -0.06583084, -0.12429786,  1.33918071, -1.02885127,
  //               -0.27698478, -0.87874371,  0.95841295, -0.86431098
  VCMP_U32(8, v1, 0x3f0e9f06, 0xbf6d8850, 0x3dcf7bff, 0x3ddde223, 0xbe3b9636,
           0x3d4e64ec, 0xbf20c32e, 0x3e821900, 0xbd86d252, 0xbdfe8fe1,
           0x3fab6a45, 0xbf83b166, 0xbe8dd0f3, 0xbf60f559, 0x3f755a8d,
           0xbf5d437b);

  VSET(16, e64, m1);
  double dscalar_64;
  //                                0.0070730785066928
  BOX_DOUBLE_IN_DOUBLE(dscalar_64, 0x3f7cf8a90de48000);
  //               -0.3542445595658672,  0.5861662785402695, 0.5713440701195280,
  //               0.2841717566030781,  0.4022451154567073, -0.9804628417449213,
  //               -0.9703836833708208,  0.2288593539727362, 0.1806576644288407,
  //               0.4892172254017777,  0.9508074316559227, -0.9022151172016701,
  //               -0.7929839752648156,  0.5513143449560454, 0.4823446191982377,
  //               -0.7486658065787619
  VLOAD_64(v2, 0xbfd6abf15f87c3c4, 0x3fe2c1dfc88b26c8, 0x3fe248735bfda932,
           0x3fd22fdebc43a768, 0x3fd9be624bf72ff4, 0xbfef5ff39c079aea,
           0xbfef0d621514ca4c, 0x3fcd4b43685929d8, 0x3fc71fca543f2eb8,
           0x3fdf4f55c3ef6448, 0x3fee6d03b4f830b0, 0xbfecdef23ccad0bc,
           0xbfe9601fee00766c, 0x3fe1a45dfb2cdc2e, 0x3fdedebbf736e98c,
           0xbfe7f511fe5c74b0);
  //               -0.7603855538897846, -0.0491604902215765,
  //               -0.3714656077097227, -0.6096204185796581,
  //               -0.2818689596683441,  0.3527700521309320, 0.1176602936422064,
  //               -0.2049443830034134, -0.6926950556538125, 0.7269529331298494,
  //               -0.2107692441818434,  0.1746722346734710,
  //               -0.5298547863982788,  0.2397543330794352,
  //               -0.8347981409736787, -0.6198539479673024
  VLOAD_64(v1, 0xbfe8551415c9d6cc, 0xbfa92b9053839560, 0xbfd7c617af2cedf8,
           0xbfe38202ae18c034, 0xbfd20a241ae21e00, 0x3fd693c8d73a46c0,
           0x3fbe1efc293b2500, 0xbfca3b9e173fd0c8, 0xbfe62a8ed24449ee,
           0x3fe74332cc30c46e, 0xbfcafa7c9161bf78, 0x3fc65ba8e7b88cc0,
           0xbfe0f4920666b5a4, 0x3fceb0451dd34270, 0xbfeab6aa9747cb24,
           0xbfe3d5d7f25a1d14);
  asm volatile("vfmsac.vf v1, %[A], v2" ::[A] "f"(dscalar_64));
  //               0.7578799543094064,  0.0533064903276678,  0.3755067691720115,
  //               0.6116303877234964,  0.2847140709489031, -0.3597049427834890,
  //               -0.1245238936163020,  0.2065631231810536, 0.6939728614971534,
  //               -0.7234926612877562,  0.2174943797906927,
  //               -0.1810536730273635,  0.5242459484866814,
  //               -0.2358548434356951,  0.8382098023325486,  0.6145585759420944
  VCMP_U64(9, v1, 0x3fe8408d7641b126, 0x3fab4afd013e6639, 0x3fd8084d8b414e68,
           0x3fe39279e4106415, 0x3fd238c15ddbf0a4, 0xbfd70567e15dbc9b,
           0xbfbfe0cc42a710ce, 0x3fca70a9114fa5b7, 0x3fe63506930e2352,
           0xbfe726da14e40fb7, 0x3fcbd6db1821e5e6, 0xbfc72cc44a3c91ef,
           0x3fe0c69f7079f20d, 0xbfce307dd3946ada, 0x3fead29d5d068eb6,
           0x3fe3aa76bf24b95e);
};

// Simple random test with similar values (vector-scalar) (masked)
void TEST_CASE4(void) {
  VSET(16, e16, m1);
  double dscalar_16;
  //                              0.3911
  BOX_HALF_IN_DOUBLE(dscalar_16, 0x3642);
  //                0.3203, -0.8521,  0.0744,  0.9370,  0.2056,  0.2866,
  //                -0.8379, -0.2668, -0.0878, -0.5703,  0.1272, -0.6606,
  //                -0.6919,  0.9189,  0.6245,  0.9932
  VLOAD_16(v2, 0x3520, 0xbad1, 0x2cc3, 0x3b7f, 0x3294, 0x3496, 0xbab4, 0xb445,
           0xad9f, 0xb890, 0x3012, 0xb949, 0xb989, 0x3b5a, 0x38ff, 0x3bf2);
  VLOAD_8(v0, 0xAA, 0xAA);
  //                0.8706,  0.4900, -0.9497,  0.4727, -0.7168,  0.0167,
  //                -0.3606, -0.1565, -0.5142,  0.8271, -0.4783,  0.6318,
  //                0.0842, -0.6646,  0.1454, -0.3020
  VLOAD_16(v1, 0x3af7, 0x37d7, 0xbb99, 0x3790, 0xb9bc, 0x2445, 0xb5c5, 0xb102,
           0xb81d, 0x3a9e, 0xb7a7, 0x390e, 0x2d63, 0xb951, 0x30a7, 0xb4d5);
  asm volatile("vfmsac.vf v1, %[A], v2, v0.t" ::[A] "f"(dscalar_16));
  //                0.8706, -0.8232, -0.9497, -0.1062, -0.7168,  0.0955,
  //                -0.3606,  0.0521, -0.5142, -1.0498, -0.4783, -0.8901,
  //                0.0842,  1.0234,  0.1454,  0.6904
  VCMP_U16(10, v1, 0x3af7, 0xba96, 0xbb99, 0xaecc, 0xb9bc, 0x2e1b, 0xb5c5,
           0x2aac, 0xb81d, 0xbc33, 0xb7a7, 0xbb1f, 0x2d63, 0x3c19, 0x30a7,
           0x3986);

  VSET(16, e32, m1);
  double dscalar_32;
  //                              -0.39704049
  BOX_FLOAT_IN_DOUBLE(dscalar_32, 0xbecb48e4);
  //                0.43844241,  0.13734208,  0.15601240,  0.48965997,
  //                -0.41457745, -0.69918746,  0.38535324,  0.83301985,
  //                0.79336989, -0.03326649, -0.85931808,  0.92554229,
  //                -0.77742523,  0.47821125, -0.53653014, -0.32442030
  VLOAD_32(v2, 0x3ee07b86, 0x3e0ca367, 0x3e1fc1b7, 0x3efab4b6, 0xbed4437f,
           0xbf32fdf3, 0x3ec54d05, 0x3f5540ca, 0x3f4b1a4a, 0xbd084272,
           0xbf5bfc45, 0x3f6cf057, 0xbf470557, 0x3ef4d81b, 0xbf095a0a,
           0xbea61a6b);
  VLOAD_8(v0, 0xAA, 0xAA);
  //               -0.73119336,  0.87333083, -0.16325396, -0.30275631,
  //               0.34779423,  0.22721651,  0.47497734, -0.58483958,
  //               -0.24916913,  0.13750601, -0.99799657,  0.66137350,
  //               0.58565408,  0.68887448, -0.74538875,  0.99311894
  VLOAD_32(v1, 0xbf3b2f7d, 0x3f5f929c, 0xbe272c0c, 0xbe9b02e0, 0x3eb21216,
           0x3e68ab72, 0x3ef3303b, 0xbf15b80c, 0xbe7f2631, 0x3e0cce60,
           0xbf7f7cb4, 0x3f294fc6, 0x3f15ed6d, 0x3f305a14, 0xbf3ed1cc,
           0x3f7e3d0b);
  asm volatile("vfmsac.vf v1, %[A], v2, v0.t" ::[A] "f"(dscalar_32));
  //               -0.73119336, -0.92786121, -0.16325396,  0.10834149,
  //               0.34779423,  0.05038923,  0.47497734,  0.25409698,
  //               -0.24916913, -0.12429786, -0.99799657, -1.02885127,
  //               0.58565408, -0.87874371, -0.74538875, -0.86431098
  VCMP_U32(11, v1, 0xbf3b2f7d, 0xbf6d8850, 0xbe272c0c, 0x3ddde223, 0x3eb21216,
           0x3d4e64ec, 0x3ef3303b, 0x3e821900, 0xbe7f2631, 0xbdfe8fe1,
           0xbf7f7cb4, 0xbf83b166, 0x3f15ed6d, 0xbf60f559, 0xbf3ed1cc,
           0xbf5d437b);

  VSET(16, e64, m1);
  double dscalar_64;
  //                                0.0070730785066928
  BOX_DOUBLE_IN_DOUBLE(dscalar_64, 0x3f7cf8a90de48000);
  //                -0.3542445595658672,  0.5861662785402695,
  //                0.5713440701195280,  0.2841717566030781, 0.4022451154567073,
  //                -0.9804628417449213, -0.9703836833708208,
  //                0.2288593539727362,  0.1806576644288407, 0.4892172254017777,
  //                0.9508074316559227, -0.9022151172016701,
  //                -0.7929839752648156,  0.5513143449560454,
  //                0.4823446191982377, -0.7486658065787619
  VLOAD_64(v2, 0xbfd6abf15f87c3c4, 0x3fe2c1dfc88b26c8, 0x3fe248735bfda932,
           0x3fd22fdebc43a768, 0x3fd9be624bf72ff4, 0xbfef5ff39c079aea,
           0xbfef0d621514ca4c, 0x3fcd4b43685929d8, 0x3fc71fca543f2eb8,
           0x3fdf4f55c3ef6448, 0x3fee6d03b4f830b0, 0xbfecdef23ccad0bc,
           0xbfe9601fee00766c, 0x3fe1a45dfb2cdc2e, 0x3fdedebbf736e98c,
           0xbfe7f511fe5c74b0);
  VLOAD_8(v0, 0xAA, 0xAA);
  //                -0.7603855538897846, -0.0491604902215765,
  //                -0.3714656077097227, -0.6096204185796581,
  //                -0.2818689596683441,  0.3527700521309320,
  //                0.1176602936422064, -0.2049443830034134,
  //                -0.6926950556538125,  0.7269529331298494,
  //                -0.2107692441818434,  0.1746722346734710,
  //                -0.5298547863982788,  0.2397543330794352,
  //                -0.8347981409736787, -0.6198539479673024
  VLOAD_64(v1, 0xbfe8551415c9d6cc, 0xbfa92b9053839560, 0xbfd7c617af2cedf8,
           0xbfe38202ae18c034, 0xbfd20a241ae21e00, 0x3fd693c8d73a46c0,
           0x3fbe1efc293b2500, 0xbfca3b9e173fd0c8, 0xbfe62a8ed24449ee,
           0x3fe74332cc30c46e, 0xbfcafa7c9161bf78, 0x3fc65ba8e7b88cc0,
           0xbfe0f4920666b5a4, 0x3fceb0451dd34270, 0xbfeab6aa9747cb24,
           0xbfe3d5d7f25a1d14);
  asm volatile("vfmsac.vf v1, %[A], v2, v0.t" ::[A] "f"(dscalar_64));
  //               -0.7603855538897846,  0.0533064903276678,
  //               -0.3714656077097227,  0.6116303877234964,
  //               -0.2818689596683441, -0.3597049427834890, 0.1176602936422064,
  //               0.2065631231810536, -0.6926950556538125, -0.7234926612877562,
  //               -0.2107692441818434, -0.1810536730273635,
  //               -0.5298547863982788, -0.2358548434356951,
  //               -0.8347981409736787,  0.6145585759420944
  VCMP_U64(12, v1, 0xbfe8551415c9d6cc, 0x3fab4afd013e6639, 0xbfd7c617af2cedf8,
           0x3fe39279e4106415, 0xbfd20a241ae21e00, 0xbfd70567e15dbc9b,
           0x3fbe1efc293b2500, 0x3fca70a9114fa5b7, 0xbfe62a8ed24449ee,
           0xbfe726da14e40fb7, 0xbfcafa7c9161bf78, 0xbfc72cc44a3c91ef,
           0xbfe0f4920666b5a4, 0xbfce307dd3946ada, 0xbfeab6aa9747cb24,
           0x3fe3aa76bf24b95e);
};

int main(void) {
  enable_vec();
  enable_fp();

  TEST_CASE1();
  TEST_CASE2();
  TEST_CASE3();
  TEST_CASE4();

  EXIT_CHECK();
}
